package com.example.practicespring.controller.login;

import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaMode;
import cn.dev33.satoken.stp.SaLoginConfig;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.practicespring.core.redis.RedisCache;
import com.example.practicespring.domain.SysUserRole;
import com.example.practicespring.domain.User;
import com.example.practicespring.log.LogModel;
import com.example.practicespring.service.SysUserRoleService;
import com.example.practicespring.service.UserService;
import com.example.practicespring.utils.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import static com.example.practicespring.utils.PwdUtils.checkPassword;
import static com.example.practicespring.utils.PwdUtils.getSHA256Hash;

@Slf4j
@RestController
@RequestMapping(value = "/user")
public class UserController {

    @Resource
    private UserService userService;

    @Resource
    private SysUserRoleService SysUserRoleService;

    @Resource
    private RedisCache redisCache;

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public SaResult login(@RequestBody User loginDTO) {
        log.info("login: {}", JsonUtil.objectToMap(loginDTO));

        String UserName = loginDTO.getName();
        String PassWord = getSHA256Hash(loginDTO.getPasswd());

        QueryWrapper<User> query = new QueryWrapper<>();
        query.eq("name", UserName);
        User one = userService.getOne(query);

        // 查询用户信息
        if (Objects.isNull(one)) {
//            判断密码是否符合要求：包含大小写字母、数字和特殊字符，长度大于8
            if (!checkPassword(loginDTO.getPasswd())){
                return SaResult.error("密码不符合要求: 包含大小写字母、数字和特殊字符，长度至少为8");
            }
            // 用户不存在直接注册
            User user = new User();
            user.setName(UserName);
            user.setPasswd(PassWord);
            user.setToken("");
            user.setIsActive(1);
            user.setUserimg("tuzi.jpg");
            userService.save(user);

            SaLoginModel newModel = SaLoginConfig.setExtraData(JsonUtil.objectToMap(user));
            StpUtil.login(user.getId(), newModel);
            String tokenValue = StpUtil.getTokenValue();
            user.setToken(tokenValue);
            userService.updateById(user);
            redisCache.setCacheObject("Token-"+tokenValue, user, 60 * 60 * 24, TimeUnit.SECONDS);

//            注册角色
            SysUserRole role = new SysUserRole();
            role.setUserid(user.getId());
            role.setRoleid(3);
            role.setDeleted(0);
            role.setCreatetime(new Date());
            SysUserRoleService.save(role);
            log.info("用户注册成功，用户名：{}", UserName);
            return SaResult.ok("用户不存在已自动注册！").setData(user);

        }

        if (PassWord.equals(one.getPasswd())) {
            if(one.getIsActive() == 0){
                return SaResult.error("用户已被禁用！");
            }
            SaLoginModel model = SaLoginConfig.setExtraData(JsonUtil.objectToMap(one));
            StpUtil.login(one.getId(), model);
            String tokenValue = StpUtil.getTokenValue();
            one.setToken(tokenValue);
            userService.updateById(one);

            // 将token存入redis缓存
            redisCache.setCacheObject("Token-"+tokenValue, one, 60 * 60 * 24, TimeUnit.SECONDS);
            StpUtil.getSession().set("Token-" + tokenValue, one);

            // 登录成功，返回用户信息
            return SaResult.data(one).setMsg("登录成功");
        } else {
            // 登录失败，返回错误信息
            return SaResult.error("用户名或密码错误");
        }
    }
}